package com.neusoft.hifly.attachment.file.api;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.neusoft.hifly.attachment.config.UploadConfig;
import com.neusoft.hifly.attachment.file.entity.FileObj;
import com.neusoft.hifly.attachment.file.service.IFileService;
import com.neusoft.hifly.commons.file.FileUtil;
import com.neusoft.hifly.commons.lang.LocalDateUtil;
import com.neusoft.hifly.commons.lang.LongUtil;
import com.neusoft.hifly.core.pojo.ApiCode;
import com.neusoft.hifly.core.pojo.ApiResponse;
import com.neusoft.hifly.core.token.TokenContextHolder;
import com.neusoft.hifly.core.utils.GlobalConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * Title: 附件服务
 * <p>
 * Description: 附件 接口
 * <p>
 * Copyright: 2019
 * <p>
 * Company: 东软汉枫
 *
 * @author lh_neu
 * @version 1.0.0
 */
@CrossOrigin
@RestController
@RequestMapping("/api/v1/attachment")
@Api(value = "attachment-api", description = "附件接口")
public class FileApi {
	@Autowired(required = false)
	private UploadConfig uploadConfig;
	@Autowired(required = false)
	private IFileService fileService;

	/**
	 * 单个文件上传
	 *
	 * @param file
	 *            文件
	 * @param objLogicId
	 *            关联ID
	 * @param objType
	 *            关联类型
	 * @return 成功信息
	 */
	@ApiOperation("单个文件上传")
	@ApiImplicitParams({ @ApiImplicitParam(name = "file", value = "文件", dataType = "__file", required = true),
			@ApiImplicitParam(name = "objLogicId", value = "关联ID", dataType = "long", required = true),
			@ApiImplicitParam(name = "objType", value = "关联类型", dataType = "string", required = true) })
	@PostMapping(value = "/upload", consumes = "multipart/*", headers = "content-type=multipart/form-data")
	public ApiResponse<?> upload(@RequestParam("file") final MultipartFile file,
			@RequestParam("objLogicId") final long objLogicId, @RequestParam("objType") final String objType)
			throws IOException {
		final String organCode = TokenContextHolder.get().getOrganCode();
		final long organLogicId = TokenContextHolder.get().getOrganLogicId();

		if (StringUtils.isEmpty(organCode) || LongUtil.isEmpty(organLogicId) || LongUtil.isEmpty(objLogicId)) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "参数错误!");
		}

		final StringBuffer p = new StringBuffer(GlobalConstants.FILE_PATH);
		p.append(File.separator);
		p.append(organCode.toUpperCase());
		p.append(File.separator);
		p.append(LocalDateUtil.dateToStr(LocalDate.now()));
		p.append(File.separator);
		p.append(FileUtil.getRandomFileName(FileUtil.getSuffix(file.getOriginalFilename())));

		FileUtil.makeDir(uploadConfig.getUploadPath() + File.separator + p.toString());

		final File f = new File(uploadConfig.getUploadPath() + File.separator + p.toString());

		//进行写入文件
		file.transferTo(f);

		final FileObj obj = new FileObj();
		obj.setOrganLogicId(organLogicId);
		obj.setFileLength(file.getSize());

		final String replace = "/" + p.toString().replace("/", "\\").replace("\\", "/").replace("//", "/");
		obj.setPath(replace); // 路径替换路径

		obj.setObjType(objType); // 关联类型
		obj.setObjLogicId(objLogicId); // 主表逻辑ID
		obj.setNewFileName(f.getName()); // 上传后的文件名称
		if (StringUtils.isNotEmpty(file.getOriginalFilename())) {
			obj.setOldFileName(file.getOriginalFilename());
		} else {
			obj.setOldFileName(obj.getNewFileName());
		}
		obj.setFileType(FileUtil.getSuffix(file.getName())); // 文件类型：.xml .jsp

		fileService.saveOrUpdate(organCode, organLogicId, obj);

		final Map<String, Object> map = new HashMap<String, Object>(2);
		map.put("obj", obj);
		map.put("fileDomain", uploadConfig.getFileDomain());
		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！", map);
	}

	/**
	 * 通过逻辑ID删除附件
	 *
	 * @param logicId
	 *            附件ID，多id使用英文逗号分隔
	 * @return 成功信息
	 */
	@ApiOperation("通过逻辑ID删除附件")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "logicId", value = "附件ID，多id使用英文逗号分隔", dataType = "string", paramType = "path", required = true) })
	@DeleteMapping(value = "/{logicId}")
	public ApiResponse<?> delete(@PathVariable("logicId") final String logicId) {
		final String organCode = TokenContextHolder.get().getOrganCode();
		final long organLogicId = TokenContextHolder.get().getOrganLogicId();

		if (StringUtils.isEmpty(organCode) || LongUtil.isEmpty(organLogicId) || StringUtils.isEmpty(logicId)) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "参数错误!");
		}

		fileService.deleteByBatch(organCode, organLogicId, logicId);
		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！");
	}

	/**
	 * 通过关联ID删除附件
	 *
	 * @param HttpServletRequest
	 *            request
	 * @return 成功信息
	 */
	@ApiOperation("通过关联ID删除附件")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "organCode", value = "租户编码", dataType = "string", paramType = "query", required = true),
			@ApiImplicitParam(name = "organLogicId", value = "租户逻辑ID", dataType = "long", paramType = "query", required = true),
			@ApiImplicitParam(name = "objLogicId", value = "关联ID", dataType = "long", paramType = "query", required = true) })
	@GetMapping(value = "/objLogicId")
	public ApiResponse<?> deleteByObjLogicId(final HttpServletRequest request) {
		final String organCode = StringUtils.trimToEmpty(request.getParameter("organCode"));
		final long organLogicId = Long.parseLong(StringUtils.trimToEmpty(request.getParameter("organLogicId")));
		final long objLogicId = Long.parseLong(StringUtils.trimToEmpty(request.getParameter("objLogicId")));

		if (StringUtils.isEmpty(organCode) || LongUtil.isEmpty(organLogicId) || LongUtil.isEmpty(objLogicId)) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "参数错误!");
		}
		fileService.deleteByObjLogicId(organCode, organLogicId, objLogicId);
		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！");
	}

	/**
	 * 下载文件
	 *
	 * @param logicId
	 *            附件ID
	 * @return 文件信息
	 */
	@ApiOperation("下载文件")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "logicId", value = "附件ID", dataType = "long", paramType = "path", required = true) })
	@GetMapping("/download/{logicId}")
	public ResponseEntity<Resource> download(@PathVariable("logicId") final long logicId) {
		final String organCode = TokenContextHolder.get().getOrganCode();
		final long organLogicId = TokenContextHolder.get().getOrganLogicId();

		if (StringUtils.isEmpty(organCode) || LongUtil.isEmpty(organLogicId) || LongUtil.isEmpty(logicId)) {
			return ResponseEntity.notFound().build();
		}

		final FileObj obj = fileService.getByLogicId(organCode, organLogicId, logicId);
		if (obj == null) {
			return ResponseEntity.notFound().build();
		}

		final String newFilePath = uploadConfig.getUploadPath() + obj.getPath();
		final File f = new File(newFilePath);

		try {
			final Resource resource = new UrlResource(f.toURI());
			return ResponseEntity.ok()
					.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + obj.getOldFileName() + "\"")
					.body(resource);
		} catch (final MalformedURLException e) {
			e.printStackTrace();
		}
		return ResponseEntity.notFound().build();
	}

	/**
	 * 查询关联类型和主表ID为条件的记录
	 *
	 * @param HttpServletRequest
	 *            request
	 * @return 部门信息
	 */
	@ApiOperation("查询关联类型和主表ID为条件的记录")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "objLogicId", value = "关联ID", dataType = "long", paramType = "query", required = true),
			@ApiImplicitParam(name = "objType", value = "关联类型", dataType = "string", paramType = "query"),
			@ApiImplicitParam(name = "orderBy", value = "自定义排序", dataType = "string", paramType = "query") })
	@GetMapping(value = "/obj")
	public ApiResponse<?> findByObjLogicId(final HttpServletRequest request) {
		final String organCode = TokenContextHolder.get().getOrganCode();
		final long organLogicId = TokenContextHolder.get().getOrganLogicId();

		final long objLogicId = Long.parseLong(StringUtils.trimToEmpty(request.getParameter("objLogicId")));
		final String objType = StringUtils.trimToEmpty(request.getParameter("objType"));
		final String orderBy = StringUtils.trimToEmpty(request.getParameter("orderBy"));

		if (LongUtil.isEmpty(organLogicId) || LongUtil.isEmpty(objLogicId)) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "参数错误!");
		}

		List<FileObj> list = null;
		if (StringUtils.isEmpty(objType)) {
			list = fileService.findByObjLogicId(organCode, organLogicId, objLogicId, orderBy);
		} else {
			list = fileService.findByObjTypeAndObjLogicId(organCode, organLogicId, objType, objLogicId, orderBy);
		}

		if (list == null) {
			return new ApiResponse<>(ApiCode.SUCCESS.getCode());
		}
		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！", list);
	}

}
